#include "stdafx.h"
#include "ftd2xx.h"
#include "DataQueue.h"
#include "Sys001.h"
#include "DrawThread.h"
#include "Session.h"

#define RETURN_IF_FAILED(ret, exit)     if(FT_OK != ret) \
                                        {\
                                            AfxMessageBox("Open device failed!");\
                                            ret = -1;\
                                            goto exit;\
                                        }
#define RETURN_IF_NULL(ptr, ret, exit)     if(NULL == ptr) \
                                        {\
                                            ret = -1;\
                                            goto exit;\
                                        }



UINT DataCollectionThread( LPVOID pParam )
{
    UINT uiRet = 0;
    
    //Get parameters
    RETURN_IF_NULL(pParam, uiRet, exit4);
    CCommSession *pCommSession;pCommSession = (CCommSession *)pParam;

    //CFile *dataFile; dataFile = new CFile();
    //dataFile->Open(_T("data1.txt"), CFile::modeReadWrite|CFile::modeNoTruncate|CFile::modeCreate);
    
    FT_STATUS ftStatus;
    DWORD dwNum;
    ftStatus = FT_ListDevices(&dwNum,NULL, FT_LIST_NUMBER_ONLY);
    if(ftStatus != FT_OK) {
        // FT_Rescan failed!        
        AfxMessageBox("FT_Rescan failed!");
        pCommSession->Stop(); 
        goto exit4;
    }  
    else if(0)
    {
        CHAR szBuffer[100];
        sprintf(szBuffer, "Device number is %d.", dwNum);       
        AfxMessageBox(szBuffer);
        goto exit4;
        
    }


    
    FT_HANDLE hDevice;
    //open devce and quit error if failed
    uiRet = FT_Open(0, &hDevice);

    if(FT_OK != uiRet)
    {
        CHAR szBuffer[100];
        sprintf(szBuffer, "Open device failed! failed code is %d.", uiRet); 
        pCommSession->Stop(); 
        AfxMessageBox(szBuffer);
        uiRet = -1;
        goto exit4;
    }


    
    //wirte start code and then check return code and quit if error 
    unsigned int tunnelCode;tunnelCode = pCommSession->GetTunnelCode();
    unsigned int frequencyCode;frequencyCode = pCommSession->GetFrequencyCode();
    unsigned char startCode;startCode = (unsigned char)((frequencyCode << 2) | (tunnelCode & 0x3));
    unsigned int stopCode;stopCode = 0x00;
    DWORD dwRetNum;

    uiRet = FT_SetTimeouts(hDevice, 1000, 1000);
    if(FT_OK != uiRet)
    {
        pCommSession->Stop(); 
        AfxMessageBox("Set time out failed!");
        uiRet = -1;
        goto exit2;
    }
    uiRet = FT_SetBaudRate(hDevice, FT_BAUD_115200);
    if(FT_OK != uiRet)
    {
        pCommSession->Stop(); 
        AfxMessageBox("Set baud rate failed!");
        uiRet = -1;
        goto exit2;     
    }
    uiRet = FT_SetDataCharacteristics(hDevice, 8, 1, FT_PARITY_NONE);
    if(FT_OK != uiRet)
    {
        pCommSession->Stop(); 
        AfxMessageBox("Set baud rate failed!");
        uiRet = -1;
        goto exit2;     
    }

    //Sleep(1000);
    uiRet = FT_Write(hDevice, &startCode, 1, &dwRetNum);
    if(FT_OK != uiRet)
    {
        pCommSession->Stop(); 
        AfxMessageBox("Write start code failed!");
        uiRet = -1;
        goto exit2;
    }

    unsigned char returnCode;
    int i;
    i = 0;
    do{
        uiRet = FT_Read(hDevice, &returnCode, 1, &dwRetNum);
        if(FT_OK != uiRet)
        {
            pCommSession->Stop(); 
            AfxMessageBox("Read start response failed!");
            uiRet = -1;
            goto exit1;
        }
        if(dwRetNum < 1)
        {
            uiRet = FT_Write(hDevice, &startCode, 1, &dwRetNum);
            if(FT_OK != uiRet)
            {
                pCommSession->Stop(); 
                AfxMessageBox("Write start code failed!");
                uiRet = -1;
                goto exit1;
            }
            i ++;
            if(i > 3)
            {
                pCommSession->Stop(); 
                AfxMessageBox("Start device timeout!");
                uiRet = -1;
                goto exit1;
            }
        }

    }while(returnCode != startCode);

    //create draw thread and save thread
    CWinThread *pDrawThread;pDrawThread = AfxBeginThread(DrawGraphicThread, pParam);
    if(NULL == pDrawThread)
    {
        pCommSession->Stop(); 
        AfxMessageBox("Create draw thread failed!");
        uiRet = -1;
        goto exit1;
    }


    //loop and read data, stop when receive stop signal
    static unsigned char aucRecvBuf[4];
    DATA_ELEM_S data;
    unsigned int recvLen;
    recvLen = ((0x1 == tunnelCode) || (0x2 == tunnelCode))?TUNNEL_DATA_LEN: TUNNEL_DATA_LEN*2;

    while(true != g_stop)
    {
        //Read data
        uiRet = FT_Read(hDevice, aucRecvBuf, recvLen, &dwRetNum);       
        if(FT_OK != uiRet)
        {
            pCommSession->Stop(); 
            AfxMessageBox("Read data failed!");
            uiRet = -1;
            goto exit1;
        }
        if(dwRetNum < recvLen)
        {
            uiRet = FT_Write(hDevice, &startCode, 1, &dwRetNum);
            if(FT_OK != uiRet)
            {
                pCommSession->Stop(); 
                AfxMessageBox("Write start code failed!");
                uiRet = -1;
                goto exit2;
            }

        }
        if(1 == tunnelCode){data.data[0][0] = aucRecvBuf[1];data.data[0][1] = aucRecvBuf[0];}
        if(2 == tunnelCode){data.data[1][0] = aucRecvBuf[1];data.data[1][1] = aucRecvBuf[0];}
        if(3 == tunnelCode){data.data[0][0] = aucRecvBuf[1];data.data[0][1] = aucRecvBuf[0];data.data[1][0] = aucRecvBuf[3];data.data[1][1] = aucRecvBuf[2];}

        theDataQueue.Write(&data);

        //save to file
        //TCHAR   szBuffer [100] ;
        //sprintf(szBuffer, "%0x %0x %0x %0x\r\n", data.data[0][0], data.data[0][1], data.data[1][0], data.data[1][1]);
        //dataFile->Write(szBuffer, strlen(szBuffer));
    }

    while(false == g_stopDraw);
    
exit1:
    //write stop signal to draw thread 
    
exit2:
	for(i=0; i<3; i++)
	{	
		uiRet = FT_Write(hDevice, &stopCode, 1, &dwRetNum);
		uiRet = FT_Close(hDevice);
	}
exit4:
    //dataFile->Close();
    theDataQueue.Clear();
    return uiRet;
}
